#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <vector>

// class Task
// {
// public:
//     Task(int a, int b):_a(a), _b(b){}

//     int Execute()
//     {
//         return _a + _b;
//     }
//     ~Task(){}
// private:
//     int _a;
//     int _b;
// };

// class Result
// {
// public:
//     Result(int result):_result(result){}

//     int GetResult() {return _result;}

//     ~Result(){}
// private:
//     int _result;
// };

// void *routine(void *args)
// {
//     Task *t = static_cast<Task*>(args);
//     sleep(100);

//     Result *res = new Result(t->Execute());
//     sleep(1);

//     // return res;

//     pthread_exit(res); // 进程退出
//     std::cout << "新线程不应该看到这里！" << std::endl;
// }

// int main()
// {
//     pthread_t tid;
//     Task *t = new Task(10, 20);
//     pthread_create(&tid, nullptr, routine , t); // 线程传递的参数可以是任意类型, 包括自定义对象

//     // int cnt = 5;
//     // while(cnt--)
//     // {
//     //     std::cout << "main线程 " << std::endl;
//     //     sleep(1);
//     // }

//     sleep(3); // 主线程和新线程谁先启动不确定
//     pthread_cancel(tid); // 在主线程处取消新线程
//     std::cout << "新线程被取消" << std::endl;

//     Result* ret = nullptr;
//     // 使用pthread_join 默认线程无异常
//     pthread_join(tid, (void**)&ret); // join: 拿到的返回值，就是线程退出时设定的返回值
//     std::cout << "新线程结束, 运行结果: " << (long long)ret << std::endl;

//     // Result* ret = nullptr;
//     // pthread_join(tid, (void**)&ret);
//     // int n = ret->GetResult();
//     // std::cout << "新线程结束, 运行结果: " << n << std::endl;

//     return 0;
// }

/////////////////////////////////////////////////////////////////////////////////////////

// void *routine(void *args)
// {
//     pthread_detach(pthread_self());
//     std::cout << "新线程被分离" << std::endl;
//     std::string name = static_cast<const char*>(args);
//     int cnt = 3;
//     while(cnt--)
//     {
//         std::cout << "新线程, name: " << name << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, routine , (void*)"thread-1");

//     // main线程分离新线程
//     // pthread_detach(tid);
//     // std::cout << "新线程被分离" << std::endl;

//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "main线程" << std::endl;
//         sleep(1);
//     }

//     int n = pthread_join(tid, nullptr);
//     if(n != 0)
//     {
//         std::cout << "pthread_join error" << strerror(n) << std::endl;
//     }
//     else
//     {
//         std::cout << "pthread_join success" << std::endl;
//     }

//     return 0;
// }

/////////////////////////////////////////////////////////////////////////////////////////

// 创建多线程

void *routine(void *args)
{
    sleep(1);
    std::string name = static_cast<const char *>(args);
    delete (char*)args;

    int cnt = 5;
    while (cnt--)
    {
        std::cout << "new线程, name: " << name << std::endl;
        sleep(1);
    }
    return nullptr;
}

const int num = 10;

int main()
{
    std::vector<pthread_t> tids;
    // 1. 创建多线程
    for (int i = 0; i < num; i++)
    {
        pthread_t tid;
        // char id[64]; // 临界区资源(临时空间) —> bug
        char *id = new char[64]; // 堆空间
        snprintf(id, 64, "thread-%d", i);
        int n = pthread_create(&tid, nullptr, routine, id);
        if (n == 0)
            tids.push_back(tid);
        else
            continue;

        // sleep(1);
    }

    // 2. 对所有线程进行等待
    for (int i = 0; i < num; i++)
    {
        int n = pthread_join(tids[i], nullptr);
        if (n == 0)
        {
            std::cout << "等待新线程成功！" << std::endl;
        }
    }

    return 0;
}
